package com.winit.openapi.wh.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.spi.context.CommandContext;
import com.winit.oms.spi.inbound.InboundItemService;
import com.winit.oms.spi.inbound.InboundMerchandiseService;
import com.winit.oms.spi.inbound.InboundPackageService;
import com.winit.oms.spi.inbound.command.AddInboundPackageCommand;
import com.winit.oms.spi.inbound.command.DeleteInboundPackageCommand;
import com.winit.oms.spi.inbound.command.ImportInboundPackageCommand;
import com.winit.oms.spi.inbound.command.OperateByKeyCommand;
import com.winit.oms.spi.inbound.command.PrintInboundPackageLabelCommand;
import com.winit.oms.spi.inbound.command.QueryInboundMerchandiseCommand;
import com.winit.oms.spi.inbound.command.QueryInboundPackageCommand;
import com.winit.oms.spi.inbound.command.QueryInboundPackinglistCommand;
import com.winit.oms.spi.inbound.command.UpdateInboundPackageCommand;
import com.winit.oms.spi.inbound.vo.InboundMerchandiseDetailsVo;
import com.winit.oms.spi.inbound.vo.InboundOrderItemVo;
import com.winit.oms.spi.inbound.vo.InboundPackageVo;
import com.winit.oms.spi.inbound.vo.InboundPackinglistVo;
import com.winit.oms.spi.inbound.vo.ResultVo;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.PDFBox4MergePDF;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.wh.builder.InboundPackageBuilder;
import com.winit.openapi.wh.validator.InboundPackagefieldValidator;

/**
 * 海外仓入库单 箱单信息
 * 
 * @version <pre>
 * Author     Version       Date        Changes
 * dinghua.an   1.0         2015年11月10日     Created
 *
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/wh/inboundPackage")
public class InboundPackageController extends BaseController {

    @Resource
    private InboundPackageService     inboundPackageService;

    @Resource
    private InboundMerchandiseService inboundMerchandiseService;
    
    @Resource
    private InboundItemService inboundItemService;

    /**
     * 商品箱单信息上传
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/importPackage")
    public String importBoxOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ImportInboundPackageCommand command = new ImportInboundPackageCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            InboundPackagefieldValidator.validPackageField(json);
            if (json.containsKey("orderNo")) {
                command.setOrderNo(json.getString("orderNo").trim());
            }
            if (json.containsKey("isFinance")) {
                command.setIsFinance(json.getString("isFinance").trim());
                if ("Y".equals(json.getString("isFinance"))) {
                    // 贷款单ID
                    if (json.containsKey("loanId")) {
                        command.setLoanId(json.getLong("loanId"));
                    }
                }
            }
            List<InboundPackageVo> voList = InboundPackageBuilder.buildPackage(json);
            command.setPackageVoList(voList);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口上传箱单信息
        ResultVo result = inboundPackageService.importInboundPackage(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("status", result.getStatus());
        data.put("msg", result.getMsg());
        responseMsg.setData(data);
        return SUCCESS;
    }


    /**
     * 查询包裹信息列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/findPackageList")
    public String findPackageList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        QueryInboundPackageCommand command = new QueryInboundPackageCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 64);
            command.setOrderNo(json.getString("orderNo"));
            Searchable searchable = InboundPackageBuilder.buildSearchPageParams(json);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());

        Page<InboundPackageVo> pagelist = inboundPackageService.queryPackageByOrderNo(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = InboundPackageBuilder.buildReturnPackageList(pagelist.getContent());

            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("packageList", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }
        return SUCCESS;

    }
    
    /**
     * 查询包裹信息列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/findPackingList")
    public String findPackingList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        QueryInboundPackinglistCommand command = new QueryInboundPackinglistCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 64);
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<InboundPackinglistVo> pagelist = inboundPackageService.queryPackingListByOrderNo(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = InboundPackageBuilder.buildReturnPackingList(pagelist);
            Map<String, Object> pageMap = new HashMap<String, Object>();
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("packinglist", datalist);
            responseMsg.setData(data);
        }
        return SUCCESS;

    }

    /**
     * 查询商品信息列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/findMerchandiseList")
    public String findMerchandiseList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        QueryInboundMerchandiseCommand command = new QueryInboundMerchandiseCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "packageId");
            ValidateUtil.validMaxLength(json, "packageId", 11);
            String packageId = json.getString("packageId");
            command.setPkgId(Long.valueOf(packageId));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<InboundMerchandiseDetailsVo> mlist = inboundMerchandiseService.queryByPackage(command);
        if (!CollectionUtils.isEmpty(mlist)) {
        	OperateByKeyCommand<String> itemCommand =  new OperateByKeyCommand<String>();
        	itemCommand.setKey(mlist.get(0).getPackageSerno());
			itemCommand.setCtx(CommandContext.getContext());
        	List<InboundOrderItemVo> itemList = inboundItemService.queryByPkgSerno(itemCommand);
            Map<String, Object> map = InboundPackageBuilder.buildReturnMerchandiseList(mlist,itemList);
            responseMsg.setData(map);
        }
        return SUCCESS;

    }

    /**
     * 编辑箱单信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updatePackageAndMerchandise")
    public String updatePackageMerchandiseList(@ModelAttribute RequestMsg requestMsg,
                                               @ModelAttribute ResponseMsg responseMsg) {

        Object obj = requestMsg.getData();
        InboundPackageVo inboundPackageVo = null;
        UpdateInboundPackageCommand command = new UpdateInboundPackageCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            InboundPackagefieldValidator.ValidEditOrderField(json);
            inboundPackageVo = InboundPackageBuilder.buildEditPackage(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setInboundPackageVo(inboundPackageVo);
        command.setCtx(CommandContext.getContext());
        inboundPackageService.updatePackageAndmerchandise(command);
//        responseMsg.setMsg("SUCCESS");
        return SUCCESS;

    }

    /**
     * 新增箱单信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/addPackage")
    public String addPackage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        InboundPackageVo vo = null;
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            InboundPackagefieldValidator.ValidBoxOrderField(json);
            vo = InboundPackageBuilder.buildAddPackage(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        AddInboundPackageCommand command = new AddInboundPackageCommand();
        command.setCtx(CommandContext.getContext());
        command.setInboundPackageVo(vo);
        inboundPackageService.addPackageAndmerchandise(command);
        responseMsg.setMsg(SUCCESS);
        return SUCCESS;
    }

    /**
     * 删除包裹信息 （支持批量）
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/deletePackage")
    public String deletePackage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        DeleteInboundPackageCommand command = new DeleteInboundPackageCommand();
        Object obj = requestMsg.getData();
        List<Long> pList = new ArrayList<Long>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 64);
            command.setOrderNo(json.getString("orderNo"));
            
            ValidateUtil.validList(json, "packageIdList", true);
            JSONArray packageIdList = json.getJSONArray("packageIdList");
            for (Object o : packageIdList) {
                JSONObject pl = (JSONObject) o;
                ValidateUtil.validNotNull(pl, "packageId");
                ValidateUtil.validMaxLength(pl, "packageId", 11);
                pList.add(pl.getLong("packageId"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        command.setPackageIdList(pList);
        inboundPackageService.deletePackage(command);
        responseMsg.setMsg(SUCCESS);
        return SUCCESS;
    }

    /**
     * 打印包裹装箱单标(支持批量打印)
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/print")
    public String printPackageLabel(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        PrintInboundPackageLabelCommand command = new PrintInboundPackageLabelCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            if (json.containsKey("packageSernoList")) {
                ValidateUtil.validNotNull(json, "orderNo", "orderNo");
                List<String> sernoList = new ArrayList<String>();
                for (Object object : json.getJSONArray("packageSernoList")) {
                    JSONObject packageSerno = (JSONObject) object;
                    ValidateUtil.validNotNull(packageSerno, "packageSerno", "packageSerno");
                    sernoList.add(packageSerno.getString("packageSerno"));
                }
                String printSize = json.getString("size");
                if(StringUtils.isEmpty(printSize)){
                	printSize = "10x10";
                }
                command.setOrderNo(json.getString("orderNo"));
                command.setPackageSernoList(sernoList);
                command.setOrigin(json.getString("origin"));
                command.setVertretung(json.getString("vertretung"));
                command.setAdresse(json.getString("adresse"));
                command.setPrintSize(printSize);
            }else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<String> bytes = inboundPackageService.printPackageLabel(command);
        PDFBox4MergePDF tool = new PDFBox4MergePDF();
        ByteArrayOutputStream out=new ByteArrayOutputStream();
        
        try {
            List<byte []> byteList= tool.decryptBASE64(bytes);
            tool.merge(byteList, out);
        } catch (IOException e) {
            throw new ApiException(ErrorCode.SYSTEM_ERROR);
        }
        Map<String, Object> dataMap=new HashMap<String, Object>();
        String mergeByte= tool.base64Encode(out.toByteArray());
        
        if (mergeByte!=null && mergeByte.length()>0) {
            dataMap.put("files", mergeByte);
        } 
        responseMsg.setData(dataMap);
        return SUCCESS;
    }
}
